#pragma once

#include <thread>
#include <atomic>
#include <queue>
#include <mutex>
#include <iostream>

extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libswscale/swscale.h>
#include <libavdevice/avdevice.h>
}

const static int WIDTH = 1920;
const static int HEIGHT = 1080;
const static int FPS = 30;

class Video
{
public:
    Video();

    void init();
    void start();

    bool getIsRunning() const;

    ~Video();

private:
    AVFormatContext *input_ctx;
    AVCodecContext *input_codec_ctx;

    SwsContext *swsContext;

    AVFormatContext *output_ctx;
    AVCodecContext *output_codec_ctx;

    std::atomic_bool isRunning;
    std::thread recvThread;
    std::thread convertThread;
    std::thread sendThread;

    // std::queue<AVFrame *> input_frame_queue;
    // std::mutex input_mutex;

    // std::queue<AVFrame *> output_frame_queue;
    // std::mutex output_mutex;

    void recv_work_fun();

    void convert_work_fun();

    void send_work_fun();

    void init_input();
    void init_output();
};